from flask import Blueprint, make_response, jsonify, request, redirect
from application.tools.captcha.captcha import captcha
from application.tools.myredis import r
from application.tools.myjwt import mjwt
from application.tools.comm import sendMsg
import json, random, time, functools,requests
from application.models.users.user import *

user_blue = Blueprint("userblue", __name__, url_prefix="/user")


# def islogin(func):
#     @functools.wraps(func)
#     def wrapper():
#         func()
#         return func()
#     return wrapper

def islogin(type):
    def pemistion(func):
        @functools.wraps(func)
        def wrapper():
            func()
            if type == 1:
                return redirect("http://www.baidu.com")
            else:
                return redirect("http://www.jd.com")
        return wrapper
    return pemistion


# 获取图片验证码
@user_blue.route("/getcode")
def getcode():
    # 生成图片验证码
    name, text, image = captcha.generate_captcha()
    # 从页面获取uuid作为redis key
    uuid = str(request.args.get('uuid'))
    # 存入redis
    r.str_add(uuid, str(text), 60)
    # 以流的方式生成图形验证码
    res = make_response(image)
    res.headers['Content-Type'] = 'image/jpg'
    return res


@user_blue.route("/sendSmsCode", methods=['POST'])
def sendSmsCode():
    data = request.data
    if data:
        data = json.loads(data)
        uuid = data['uuid']
        piccode = data['piccode']
        mobile = data['mobile']
        value = r.str_get(uuid)
        if value:
            if piccode.lower() == value.lower():
                mcode = r.str_get(mobile)
                if mcode:
                    return jsonify({"code": 10012, "mes": '一分钟内不能重复发'})
                scode = random.randint(10000, 99999)
                print(scode)
                flag = sendMsg(mobile, scode)
                if flag == True:
                    r.str_add(mobile, scode, 60)
                    r.del_str(uuid)
                    return jsonify({"code": 200, 'mes': '发送成功'})
                else:
                    return jsonify({"code": 200, 'mes': '发送验证码失败'})
            else:
                return jsonify({"code": 10011, 'mes': '图片验证码错误'})
        else:
            return jsonify({"code": 10010, 'mes': '图片验证码不存在'})


@user_blue.route("/login", methods=['POST'])
def login():
    data = request.data
    if data:
        data = json.loads(data)
        mcode = data['code']
        mobile = data['mobile']
        code = r.str_get(mobile)
        if code:
            if int(code) == int(mcode):
                user = User.query.filter(User.mobile == mobile).first()
                if user:
                    r.del_str(mobile)
                else:
                    u = User(mobile=mobile, nikename=mobile)
                    db.session.add(u)
                    db.session.commit()
                    user = User.query.filter(User.mobile == mobile).first()
                    token = mjwt.jwt_encdoe(data={"data":{'uid':user.id,'exp':int(time.time())}})
                return jsonify({"code":200, 'token':token, 'userid':user.id})
            else:
                return jsonify({"code":10021, 'mes':'验证码错误'})
        else:
            return jsonify({"code":10020, 'mes':''})

# 获取weibo地址
@user_blue.route("/getwburl")
def getwburl():
    client_id="3674019597"
    redirect_uri="http://127.0.0.1:8000/user/weiboCallback/"
    url = "https://api.weibo.com/oauth2/authorize?client_id=%s&response_type=code&redirect_uri=%s"%(client_id,redirect_uri)
    return jsonify({"code":200,"url":url})

# weibo回调接口
@user_blue.route("/weiboCallback/")
def weiboCallback():
    # 获取code
    code = request.args.get('code')
    # 向access_token接口发起post请求
    data = {"client_id": '3674019597', "client_secret": "7ae99bc0d54ead29fc8d1b9fabd78587",
            "grant_type": "authorization_code",
            'redirect_uri': "http://127.0.0.1:8000/user/weiboCallback/", 'code': code}
    res = requests.post('https://api.weibo.com/oauth2/access_token', data=data)
    print(res.text)
    # 解析参数，token,uuid
    mes = json.loads(res.text)
    token = mes['access_token']
    uid = mes['uid']
    # 查询三方登陆中uid是否存在，如果存在，查询用户表，用用户信息生成token跳转到vue页面
    sql = "select user.id from user inner join sf_login on user.id=sf_login.userid where sf_login.uid='%s'" % (uid)
    user = db.session.execute(sql)
    # 判断是否查询到
    if user:
        for i in user:
            data = {"data": {"user.id": i[0], "exp": int(time.time())}}
            # token = mjwt.jwt_encode(data)
            token = mjwt.jwt_encode(data)
            return redirect("http://localhost:8080/#/updateToken?userid=" + str(i[0]) + "&token=" + token)

    # 不存在跳转到vue绑定页面，token uuid传递过去
    return redirect('http://localhost:8080/#/bindMobile?uid=' + uid + "&token=" + token)


# 绑定手机号
@user_blue.route("/bindMobile", methods=['POST'])
def bindMobile():
    data = json.loads(request.data)
    mobile = data['mobile']
    uid = data['uid']
    token = data['token']
    # 先查询用户表，如果手机号存在
    user = User.query.filter(User.mobile == mobile).first()
    if not user:
        # 添加用户
        u = User(mobile=mobile, nikename=mobile)
        db.session.add(u)
        db.session.commit()
        # 获取用户信息
        user = User.query.filter(User.mobile == mobile).first()

    sfuser = SfLogin(userid=user.id, webfrom='wb', uid=uid, token=token)
    db.session.add(sfuser)
    db.session.commit()
    # 如果不存在，写入user表
    # 获取userid，写入三方登录表，生成token返回
    data = {"data": user.id, "exp": int(time.time())}
    token = mjwt.jwt_encode(data)
    return jsonify({"userid": str(user.id), 'token': token})


# 购买vip生成订单
@user_blue.route("/buy",methods=['POST'])
def buy():
    # 获取参数
    data = json.loads(request.data)
    userid = data['userid']
    year = data['year']
    money = 200
    tmoney = money * int(year)
    order_no = str(int(time.time()))+str(userid)
    viprecord = VipRecord(order_no=order_no,userid=userid,year=year,money=tmoney,active_money=tmoney,status=1)
    db.session.add(viprecord)
    db.session.commit()
    # 支付，返回支付url
    pay = get_ali_object()
         # 生成支付的url
    # 订单号重构充值1  支付订单2
    orders = str(order_no)+":"+str(1)
    query_params = pay.direct_pay(
        subject="test",  # 商品简单描述
        out_trade_no=str(orders),  # 用户购买的商品订单号（每次不一样） 20180301073422891
        total_amount=float(1.00),  # 交易金额(单位: 元 保留俩位小数)
    )
    pay_url = "https://openapi.alipaydev.com/gateway.do?{0}".format(query_params)  # 支付宝网关地址（沙箱应用）
    return jsonify({"code":200,'url':pay_url})


from application.tools.comm import get_ali_object
import datetime
@user_blue.route("/callback")
def callback():
    # 接收参数
    data = request.args
    datames = {k:v for k,v in data.items()}
    # 删除字典中eky为sign的记录
    sign = datames.pop('sign')
    # 鉴权 订单号 流水号
    pay = get_ali_object()
    flag = pay.verify(datames,sign)
    if flag == True:
        # 支付宝流水号
        transaction_no = datames['trade_no']
        # 订单号
        order_no = datames['out_trade_no']
        # split订单号
        orderlist = order_no.split[":"]
        order_no = orderlist[0]
        type = int(orderlist[1])
        # 事务处理
        try:
            if type == 1:
                # 订单号更新订单表
                record = VipRecord.query.filter(VipRecord.order_no==order_no).first()
                record.status = 2
                record.transaction_no=transaction_no
                db.session.add(record)
                # 更新用户表
                User.query.filter(User.id==record.userid).update({"level":2})
                # 更新vip表
                vip = Vip.query.filter(Vip.userid==record.userid,Vip.status==1).first()
                if vip is not None:
                    # 结束时间+购买年限
                    etime = vip.e_time.split("-")
                    tyear = int(etime[0])+int(record.year)
                    yearstr="-"
                    etime[0] = str(tyear)
                    retime = yearstr.join(etime)
                    vip.e_time = retime
                    db.session.add(vip)
                else:
                    # nowyear = datetime.date.strftime(datetime.datetime.now(),"%Y-$m-%d %H:%m:%s")
                    # etime = nowyear.split("-")
                    # tyear = int(etime[0])+int(record.year)
                    # etime[0] = str(tyear)
                    # yearstr="-"
                    # retime = yearstr.join(etime)
                    year = 365 * int(record.year)
                    retime = datetime.datetime.now() + datetime.timedelta(days=year)
                    vip = Vip(userid=record.userid, s_time=datetime.datetime.now(), e_time=retime)
                    db.session.add(vip)
                db.session.commit()
            elif type == 2:
                # 课程订单更新状态，支付宝的流水号
                orders = Orders.query.filter(Orders.order_no == order_no).first()
                orders.status = 2
                orders.trans_no = transaction_no
                db.session.add(orders)
                # 更新订单表状态，根据订单详情表查询商品，去商品表中减少商品汇总库存
                for i in orders.details:
                    tcourse = Tcourse.query.filter(Tcourse.id==i.courseid).first()
                    tcourse.store = tcourse.store - i.number
                    db.session.add(tcourse)
                db.session.commit()
        except:
            db.session.rollback()
    else:
        print("鉴定失败")
    return 'ok'


@user_blue.route("/getTags")
def getTags():
    tags = Tags.query.all()
    tagslist = [{"id":i.id,'name':i.name} for i in tags]
    types = Ctype.query.all()
    typeslist = [{"id": i.id, 'name': i.name} for i in types]
    ctype = CourseType.query.all()
    clist = [{"id": i.id, 'name': i.name} for i in ctype]
    return jsonify({"code":200,'tags':tagslist,'types':typeslist,'clist':clist})


from qiniu import Auth
# 获取七牛云token
@user_blue.route("/get_qntoken")
def get_qntoken():
    # -*- coding: utf-8 -*-

    # 需要填写你的 Access Key 和 Secret Key
    access_key = 'KeEewyWQeXzfxIKQvNhxkbswdTeKUPWZkd-N1JGZ'
    secret_key = '3V0KC-G4AiMPT3Lz3-EcG-67Pe3Ls7VzXxg4r02A'

    # 构建鉴权对象
    q = Auth(access_key, secret_key)

    # 要上传的空间
    bucket_name = 'h2205aa'


    # 3600为token过期时间，秒为单位。3600等于一小时
    token = q.upload_token(bucket_name)

    return jsonify({"code":200,'token':token})


@user_blue.route('/addCourse',methods=['POST'])
def addCourse():
    try:
        # 获取参数
        data = json.loads(request.data)
        # 写入课程表
        course = Course(name=data['name'],url=data['url'],descrip=data['desc'],ctype=data['type'])
        db.session.add(course)
        scourse = Course.query.filter(Course.name == data['name']).first()
        # 写入课程标签表
        for i in data['tags']:
            sql = "insert into course_tag(courseid,tagid) values(%d,%d)"%(scourse.id,int(i))
            db.session.execute(sql)
        # 课程分类表
        for i in data['ctype']:
            sql = "insert into course_cate(courseid,course_typeid) values(%d,%d)"%(scourse.id,int(i))
            db.session.execute(sql)
        db.session.commit()
        return jsonify({"code": 200})
    except:
        db.session.rollback()
    return jsonify({"code":400})


import math
# @user_blue.route("/getCourse")
# def getCourse():
#     # 获取参数page
#     page = int(request.args.get("page"))
#     # 获取上线、即将上线条件
#     online = request.args.get('is_publish')
#     # 查询总条数
#     total = Course.query.filter(Course.is_publish==online).count()
#     # 定义每页显示多少条
#     page_size = 2
#     # 查询当前页记录
#     start = math.ceil((page-1)*page_size)
#     #select * from course limit start,page_size
#     # 获取排序字段
#     orderpara = request.args.get('orderpara')
#     if orderpara == 'new':
#         course = Course.query.order_by(Course.create_time.desc()).filter(Course.is_publish==online).offset(start).limit(page_size).all()
#     else:
#         course = Course.query.order_by(Course.views.desc()).filter(Course.is_publish == online).offset(start).limit(
#             page_size).all()
#     list = [{"id":i.id,'name':i.name,'url':i.url,'views':i.views} for i in course]
#     # 返回结果
#     return jsonify({"code":200,'clist':list,'total':total,'page_size':page_size})


@user_blue.route("/getCourse")
def getCourse():
    # 获取当前页面
    page = int(request.args.get('page'))
    page_size = 2
    # 获取条件
    # 获取上线，即将上线条件
    online = int(request.args.get('is_publish'))
    # 获取类别
    types = int(request.args.get('types'))
    # 获取类别
    tags = int(request.args.get('tags'))
    # 获取排序字段
    orderpara = request.args.get('orderpara')

    # 重构where条件
    where = "1=1"

    if online:
        where = where + " and c.is_publish="+str(online)
    if types>0:
        where = where + " and c.ctype="+str(types)
    orderby = " order by c.views desc"
    if orderpara == "new":
        orderby = " order by c.create_time desc"
    start = math.ceil((page-1)*page_size)
    # 查询一共有多少条记录
    if tags >0:
        countsql = " select count(c.id) as tcount from course as c inner join course_tag as ct on c.id=ct.courseid where ct.tagid="+str(tags)+" and "+where
    else:
        countsql = " select count(c.id) as tcount from course as c where " +where
    cres = db.session.execute(countsql)
    cdata = cres.fetchone()
    total = cdata['tcount']
    # 查询当前页记录
    if tags >0:
        sql = "select c.* from course as c inner join course_tag as ct on c.id=ct.courseid where ct.tagid="+str(tags)+" and "+where+orderby+" limit "+str(start)+","+str(page_size)
    else:
        sql = "select c.* from course as c where "+where+orderby+" limit "+str(start)+","+str(page_size)
    res = db.session.execute(sql)
    data = res.fetchall()
    clist = [{"id":i.id,'name':i.name,'url':i.url,'views':i.views,} for i in data]
    return jsonify({"code":200,'total':total,'page_size':page_size,'clist':clist})
